﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using WCBG.ToolsForUnity.Tools;

/// <summary>
/// 拖枕木游戏
/// </summary>
public class DragTrainTrackPart : StudyMathBasePart
{


    private const string scenePath = StudyPath.math_dragtraintrack_scene;
    private const string zhenmuPath = StudyPath.math_zhenmuPath;    // 枕木
    private const float HINT_INTERVAL_TIME = 3;    // 无操作检测间隔时间
    private const float AUDIO_INTERVAL_TIME = 15;    // 语音提示时间 这个只播一次

    private readonly float checkWoodDragMinDis = 50f; //拖动枕木检测距离
    private readonly float trainOutTime = 5f; // 火车离开时间

    private Transform m_TrainOutPoint;
    private TrainHeadActor m_TrainHeadActor;
    private TrainNodeActor m_TrainNodeActor1;
    private TrainNodeActor m_TrainNodeActor2;
    private WoodActor m_currentDragWood;    // 当前拖动的枕木
    private GameAudioSource m_trainLoopAudio;   // 火车循环跑动音效

    private Vector3 m_dragStartPoint;    // 拖动的初始点击坐标
    private bool bPlayFirstAudio;
    private bool bLockInput;
    //private bool isTrainMoveOut;
    private int hintTimeID;
    private int audioTimeID;
    private int m_woodCount;    // 记录当前拖拽了几个

    private int[] allPlayNumberArray;
    private int m_playNumber; //当前游戏数字
    //private int m_currentDragIndex;
    
    private List<WoodActor> m_AllWoodMissList = new List<WoodActor>();    // 火车轨道的缺口列表
    private List<WoodActor> m_CurrentWoodMissList = new List<WoodActor>();    // 火车轨道的显示列表
    private List<WoodActor> m_CreateWoodList = new List<WoodActor>();    // 创建的枕木列表
    private List<WoodActor> m_DragWoodList = new List<WoodActor>();    // 剩下待拖拽的枕木列表
    private List<int> playNumberList = new List<int>();    // 当前玩的数字列表


    protected override void OnPartStart(params object[] paramArray)
    {
        base.OnPartStart(paramArray);

        allPlayNumberArray = ((List<int>)paramArray[0]).ToArray();
        bPlayFirstAudio = (bool)paramArray[1];
        //bIsTrainMoving = false;
        bLockInput = true;
        //isTrainMoveOut = false;
        m_woodCount = 0;

        CreateScene(scenePath);

        m_playNumber = GetPlayNumber();
        Debug.Log("--------------------: start play number: " + m_playNumber);

        CreateDragZhenmu();
        SetRandomTrainTrack(m_playNumber);
        InitTrain();

        if (hintTimeID > 0)
            InputTimerManager.Instance.RemoveTimerNoInput(hintTimeID);
        if (audioTimeID > 0)
            InputTimerManager.Instance.RemoveTimerNoInput(audioTimeID);
        if (bPlayFirstAudio)
        {
            playNumberList.Clear();

            this.PlayActionAudioEx(ActionAudioName.t_1004, () =>
            {
                ShowNumberWood(m_playNumber, () =>
                {
                    foreach (WoodActor mono in m_CreateWoodList)
                    {
                        mono.EnableCollision(true);
                    }
                    bLockInput = false;
                });

                hintTimeID = InputTimerManager.Instance.AddTimerNoInput(HINT_INTERVAL_TIME, true, OnLeaveInput);
                audioTimeID = InputTimerManager.Instance.AddTimerNoInput(AUDIO_INTERVAL_TIME, false, PlayLeaveAudio);
            });
            
        }
        else
        {
            hintTimeID = InputTimerManager.Instance.AddTimerNoInput(HINT_INTERVAL_TIME, true, OnLeaveInput);
            audioTimeID = InputTimerManager.Instance.AddTimerNoInput(AUDIO_INTERVAL_TIME, false, PlayLeaveAudio);
            ShowNumberWood(m_playNumber, () =>
            {
                foreach (WoodActor mono in m_CreateWoodList)
                {
                    mono.EnableCollision(true);
                }
                bLockInput = false;
            });
        }

        playNumberList.Add(m_playNumber);
    }

    protected override void OnPartExit()
    {
        base.OnPartExit();

        if (hintTimeID > 0)
            InputTimerManager.Instance.RemoveTimerNoInput(hintTimeID);
        if (audioTimeID > 0)
            InputTimerManager.Instance.RemoveTimerNoInput(audioTimeID);

        hintTimeID = 0;
        audioTimeID = 0;
        m_woodCount = 0;

        //isTrainMoveOut = false;
        m_currentDragWood = null;
        m_TrainOutPoint = null;
        m_TrainHeadActor = null;
        m_TrainNodeActor1 = null;
        m_TrainNodeActor2 = null;
        m_AllWoodMissList.Clear();
        m_CurrentWoodMissList.Clear();
        m_CreateWoodList.Clear();
        m_DragWoodList.Clear();
        allPlayNumberArray = null;
        if (m_trainLoopAudio != null) m_trainLoopAudio.Stop();
        m_trainLoopAudio = null;
        //System.Array.Clear(allPlayNumberArray, 0, allPlayNumberArray.Length);
    }

    protected override void OnMouseDown()
    {
        Transform target = FTools.GetRaycastHitTargetByMousePoint();
        if (target == null)
            return;

        if (target.GetComponent<MuBanActor>() == null && target.GetComponent<WoodActor>() == null && target.gameObject.layer != (int)EGameLayerMask.Floor)
        {
            target.AddComponentEx<StudyFixedActor>().CrossFade(StudyFixedActor.AnimatorNameEnum.Jump, 0.01f);
            return;
        }

        MuBanActor muBanActor = target.GetComponent<MuBanActor>();
        if (muBanActor != null)
        {
            muBanActor.CrossFade(MuBanActor.AnimatorNameEnum.Shake, 0.01f);
        }

        WoodActor wood = target.GetComponent<WoodActor>();
        if (wood != null && !wood.IsComplete)
        {
            if (bLockInput)
            {
                wood.CrossFade(WoodActor.AnimatorNameEnum.Jump, 0.01f);
                this.PlayAudioEx(StudyAudioName.t_11008);
            }
            else
            {
                this.PlayAudioEx(StudyAudioName.t_11014);
                DragTargetStart(wood);
            }
        }
        //this.PlayAudioEx(11004);
    }

    protected override void OnMouseHover()
    {
        if (m_currentDragWood != null)
        {
            RaycastHit hit;
            if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, 9999, 1 << (int)EGameLayerMask.Floor))
            {
                Vector3 newPoint = hit.point;
                Vector3 offsetDir = newPoint - m_dragStartPoint;
                m_dragStartPoint = newPoint;
                m_currentDragWood.transform.position += offsetDir;

                foreach (WoodActor mono in m_CurrentWoodMissList)
                {
                    float dis = Vector3.Distance(m_currentDragWood.transform.position, mono.transform.position);
                    if (dis < checkWoodDragMinDis)
                    {

                        m_currentDragWood.DragComplete(mono.transform.position, mono.transform.rotation);
                        m_currentDragWood.EnableCollision(false);
                        m_DragWoodList.Remove(m_currentDragWood);
                        m_CurrentWoodMissList.Remove(mono);
                        ResetDragTarget();
                        GameAudioSource audio = this.PlayAudioEx(StudyAudioName.t_11009);
                        int index = m_woodCount;
                        AddTimer(audio.Length, () => {
                            this.PlayAudioEx((uint)(StudyAudioName.t_12006 + index));
                        });

                        m_woodCount++;
                        if (m_CurrentWoodMissList.Count < 1)
                            PlayTrainOutAnimation();
                        //Debug.Log("----------: m_CurrentWoodMissList : " + m_CurrentWoodMissList.Count);
                        break;
                    }
                }
            }
        }
    }

    protected override void OnMouseUp()
    {
        if (m_currentDragWood != null)
        {
            DragTargetEnd();
        }
    }

    private void DragTargetStart(WoodActor target)
    {
        //Debug.Log("----------: DragTargetStart! target:" + target.name);
        m_currentDragWood = target;
        m_currentDragWood.EnableScaleAnimation(true);
        RaycastHit hit;
        if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, 99999, 1 << (int)EGameLayerMask.Floor))
        {
            m_dragStartPoint = hit.point;
        }
    }

    private void DragTargetEnd()
    {
        if (m_currentDragWood == null)
            return;
        //Debug.Log("----------: DragTargetEnd! target:" + m_currentDragWood.name);

        m_currentDragWood.EnableScaleAnimation(false, 0.3f);
        m_currentDragWood.ResetStartPositionAndRotation(0.3f);
        m_currentDragWood = null;
    }

    private void ResetDragTarget()
    {
        if (m_currentDragWood == null)
            return;
        m_currentDragWood = null;
    }

    // 火车开走
    private void PlayTrainOutAnimation()
    {
        //Debug.Log("----------: PlayTrainOutAnimation!");
        bLockInput = true;

        AddTimer(1000, () =>
        {

            //bIsTrainMoving = true;
            m_TrainHeadActor.CrossFade(TrainHeadActor.AnimatorNameEnum.Zoom, 0.01f);
            m_TrainNodeActor1.CrossFade(TrainNodeActor.AnimatorNameEnum.UpAndDown, 0.01f);
            m_TrainNodeActor2.CrossFade(TrainNodeActor.AnimatorNameEnum.UpAndDown, 0.01f);
            //PlayMathAudio(StudyAudioName.TrainWhistleAudio);
            this.PlayAudioEx(StudyAudioName.t_11001);

            AddTimer(2000, () =>
            {
                float maxMoveTime = trainOutTime;
                float pathDis = Vector3.Distance(m_TrainOutPoint.position, m_TrainHeadActor.transform.position);
                float pathDis1 = Vector3.Distance(m_TrainOutPoint.position, m_TrainNodeActor1.transform.position);
                float pathDis2 = Vector3.Distance(m_TrainOutPoint.position, m_TrainNodeActor2.transform.position);
                float timeDis = pathDis / maxMoveTime;
                float maxTime = pathDis2 / timeDis;

                m_TrainHeadActor.transform.DOMove(m_TrainOutPoint.position, maxMoveTime).SetEase(Ease.Linear);
                m_TrainNodeActor1.transform.DOMove(m_TrainOutPoint.position, pathDis1 / timeDis).SetEase(Ease.Linear);
                m_TrainNodeActor2.transform.DOMove(m_TrainOutPoint.position, pathDis2 / timeDis).SetEase(Ease.Linear);

                m_TrainHeadActor.CrossFade(TrainHeadActor.AnimatorNameEnum.Move, 0.01f);
                m_TrainNodeActor1.CrossFade(TrainNodeActor.AnimatorNameEnum.Move, 0.01f);
                m_TrainNodeActor2.CrossFade(TrainNodeActor.AnimatorNameEnum.Move, 0.01f);

                m_TrainHeadActor.PlayEffect(StudyPath.math_traineffect_out);

                m_trainLoopAudio = this.PlayAudioEx(StudyAudioName.t_11002);

                AddTimer(maxTime, () =>
                {
                    m_trainLoopAudio.Stop();
                    m_trainLoopAudio = null;

                    //this.PlayAudioEx(StudyAudioName.t_11018);
                    MedalWindow.Instance.ShowXunzhang(playNumberList.Count, true, MedalWindow.EXZCountEnum.Four, () =>
                    {
                        OnGamePartComplete();
                    });
                });
            });
        });
    }

    private void OnGamePartComplete()
    {
        //PlayMathAudio(StudyAudioName.SucceedAudio);

        //MathNumberWindow.Instance.ShowXunzhang(playNumberList.Count, true, MathNumberWindow.EXZCountEnum.Four, () => {

            OnPartComplete(true, m_playNumber);
        //});
    }

    // 无操作事件
    private void OnLeaveInput(int seq)
    {
        if (bLockInput)
            return;
        m_TrainHeadActor.CrossFade(TrainHeadActor.AnimatorNameEnum.UpAndDown, 0.01f);
        m_TrainNodeActor1.CrossFade(TrainNodeActor.AnimatorNameEnum.RightAneLeft, 0.01f);
        m_TrainNodeActor2.CrossFade(TrainNodeActor.AnimatorNameEnum.RightAneLeft, 0.01f);
        AddTimer(Random.Range(1000, 1500), () => {

            PlayRandomWoodAnimation();
        });
        
        //PlayMathAudio(StudyAudioName.TrainNodeJumpAudio);
        //PlayMathAudio(StudyAudioName.TrainNodeLRJumpAudio);
    }

    private void PlayLeaveAudio(int seq)
    {
        if (bLockInput)
            return;
        this.PlayAudioEx(StudyAudioName.t_12033);
    }

    private void PlayRandomWoodAnimation()
    {
        WoodActor actor = m_DragWoodList[Random.Range(0, m_DragWoodList.Count)];
        actor.CrossFade(WoodActor.AnimatorNameEnum.Jump, 0.01f);

        //PlayMathAudio(StudyAudioName.ZhenmuJumpAudio);
        this.PlayAudioEx(StudyAudioName.t_11008);
    }

    // 创建待拖拽枕木
    private void CreateDragZhenmu()
    {
        List<string> woodCreateList = new List<string>() {
            "createwood/303020501_1",
            "createwood/303020501_2",
            "createwood/303020501_3",
            "createwood/303020501_4",
            "createwood/303020501_5",
            "createwood/303020501_6",
            "createwood/303020501_7",
            "createwood/303020501_8",
            "createwood/303020501_9",
            "createwood/303020501_10",
            "createwood/303020501_11"
        };


        Resource res = ResourceManager.Instance.GetResource(zhenmuPath, typeof(GameObject), enResourceType.ScenePrefab);
        if (res.m_content != null)
        {
            for (int i = 0; i < woodCreateList.Count; i++)
            {
                Transform target = Scene.Find(woodCreateList[i]);
                
                GameObject woodObj = Instantiate(res.m_content as GameObject, true);
                woodObj.transform.parent = target.parent;
                //woodObj.transform.position = target.position;
                //woodObj.transform.rotation = target.rotation;
                //woodObj.transform.rotation = Quaternion.Euler(0, Random.Range(-90, 90), 0);
                WoodActor mono = woodObj.AddComponent<WoodActor>();
                mono.EnableCollision(false);
                mono.Initialize(target.position, Quaternion.Euler(0, Random.Range(-90, 90), 0));

                m_CreateWoodList.Add(mono);
                m_DragWoodList.Add(mono);
            }

        }
    }

    // 设置随机铁轨
    private void SetRandomTrainTrack(int number)
    {
        Transform trackParent = Scene.Find("wood_10");

        List<int> randomList = new List<int>() { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
        m_AllWoodMissList.Clear();
        m_CurrentWoodMissList.Clear();

        for (int i = 0; i < number; i++)
        {
            int randomNumber = Random.Range(0, randomList.Count);
            int value = randomList[randomNumber];
            Transform target = trackParent.GetChild(value);
            WoodActor mono = target.gameObject.AddComponentEx<WoodActor>();
            mono.EnableWood(false);
            m_AllWoodMissList.Add(mono);
            m_CurrentWoodMissList.Add(mono);

            randomList.Remove(value);
        }
    }

    // 初始火车
    private void InitTrain()
    {
        string path1 = "Train/303020101_head";
        string path2 = "Train/303020202_blue_anim";
        string path3 = "Train/303020202_green_anim";
        string path4 = "Train/OutPoint";

        m_TrainHeadActor = Scene.Find(path1).gameObject.AddComponent<TrainHeadActor>();
        m_TrainNodeActor1 = Scene.Find(path2).gameObject.AddComponent<TrainNodeActor>();
        m_TrainNodeActor2 = Scene.Find(path3).gameObject.AddComponent<TrainNodeActor>();
        m_TrainOutPoint = Scene.Find(path4);

    }

    private void ShowNumberWood(int number, System.Action callback)
    {
        string path1 = "303020504_move/303020504";
        string path2 = "303020504_move";

        Transform numberWood = Scene.Find(path1);
        Transform movePoint = Scene.Find(path2);

        MuBanActor actor = numberWood.gameObject.AddComponent<MuBanActor>();
        actor.SetNumberTexture(number);
        actor.GetComponent<BoxCollider>().enabled = false;
        numberWood.DOMove(movePoint.position, 0.5f).SetEase(Ease.OutSine).OnComplete(() => {

            actor.GetComponent<BoxCollider>().enabled = true;
            if (callback != null)
            {
                callback();
            }
        });

        //PlayMathAudio(StudyAudioName.HintCardInAudio);
        this.PlayAudioEx(StudyAudioName.t_11007);

    }

    private int GetPlayNumber()
    {
        List<int> list = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        //Debug.Log("--------------------: allPlayNumberArray:: " + allPlayNumberArray.Length);
        for (int i = 0; i < allPlayNumberArray.Length; i++)
        {
            list.Remove(allPlayNumberArray[i]);
        }

        return list[Random.Range(0, list.Count)];
    }


}
